// 执行命令  ts-node typeWidening.ts
// 类型拓宽
let str12 = 'this is string'; // 类型是 string
let strFun = (str12 = 'this is string') => str12; // 类型是 (str12?: string) => string;
const specifiedStr1 = 'this is string'; // 类型是 'this is string'
let str2 = specifiedStr1; // 类型是 'string'
let strFun2 = (str12 = specifiedStr1) => str12; // 类型是 (str12?: string) => string;

interface Vector3 {
  x: number;
  y: number;
  z: number;
}
function getComponent(vector: Vector3, axis: "x" | "y" | "z") {
  return vector[axis];
}
// let xx = 'x'
const xx = 'x'
let vec = { x: 10, y: 20, z: 30 };
// 类型“string”的参数不能赋给类型“"x" | "y" | "z"”的参数。
getComponent(vec, xx); // let xx 会Error

// const 对于对象
const objW = { 
  x: 1,
};
objW.x = 6; // OK 
// 不能将类型“string”分配给类型“number”。
// objW.x = '6'; // Error
// 类型“{ x: number; }”上不存在属性“y”。
// objW.y = 8; // Error
// 类型“{ x: number; }”上不存在属性“name”。
// objW.name = 'semlinker'; // Error
// 解决const类型拓宽
const objW1: { x: 1 | 3 | 5 } = {
  x: 1
}
// 使用const断言
const objW2 = {
  x: 1 as const, // 1
  y: 2 // number
}
const objW3 = {
  x: 1, // readonly 1
  y: 2  // readonly 2
} as const
// objW2.x = 2 // Error
objW2.y = 2
// objW3.x = 2
// objW3.y = 2
// 使用数组断言
const arrW1 = [1, 2] // number[]
const arrW2 = [1, 2] as const // readonly [1, 2]
arrW1[0] = 2
// arrW2[0] = 1 // Error

console.log('typeWidening: ', getComponent({ x: 1, y: 2, z: 3 }, "x"))